Even though standards-based application software (e.g., Java based application software) has the potential to offer true competition at the software supplier level, legacy proprietary software has proven reliability, functionality and integration into customer information systems (IS) infrastructures. Customers are therefore placing operational dependency on standards-based software technologies with caution. Not surprisingly, present day application software servers tend to include instances of both standard and proprietary software suites, and, often, “problems” emerge in the operation of the newer standards-based software, or interoperation and integration of the same with legacy software applications.
The prior art application server 100 depicted in FIG. 1A provides a good example. FIG. 1A shows a prior art application server 100 having both an ABAP legacy/proprietary software suite 103 and a Java J2EE standards-based software suite 104. A connection manager 102 routes requests (e.g., HTTP requests, HTTPS requests) associated with “sessions” between server 100 and numerous clients (not shown) conducted over a network 101. A “session” can be viewed as the back and forth communication over a network 101 between computing systems (e.g., a particular client and the server.
The back and forth communication typically involves a client (“client”) sending a server 100 (“server”) a “request” that the server 100 interprets into some action to be performed by the server 100. The server 100 then performs the action and if appropriate returns a “response” to the client (e.g., a result of the action). Often, a session will involve multiple, perhaps many, requests and responses. A single session through its multiple requests may invoke different application software programs.
For each client request that is received by the application server's connection manager 102, the connection manager 102 decides to which software suite 103, 104 the request is to be forwarded. If the request is to be forwarded to the proprietary software suite 103, notification of the request is sent to a proprietary dispatcher 105, and, the request itself is forwarded into a request/response shared memory 106. The proprietary dispatcher 105 acts as a load balancer that decides which one of multiple proprietary worker nodes 1071 through 107N are to actually handle the request.
A worker node is a focal point for the performance of work. In the context of an application server that responds to client-server session requests, a worker node is a focal point for executing application software and/or issuing application software code for downloading to the client. The term “working process” generally means an operating system (OS) process that is used for the performance of work and is also understood to be a type of worker node. For convenience, the term “worker node” is used throughout the present discussion.
When the dispatcher 105 identifies a particular proprietary worker node for handling the aforementioned request, the request is transferred from the request/response shared memory 106 to the identified worker node. The identified worker node processes the request and writes the response to the request into the request/response shared memory 106. The response is then transferred from the request/response shared memory 106 to the connection manager 102. The connection manager 102 sends the response to the client via network 101.
Note that the request/response shared memory 106 is a memory resource that each of worker nodes 1071 through 107L has access to (as such, it is a “shared” memory resource). For any request written into the request/response shared memory 106 by the connection manager 102, the same request can be retrieved by any of worker nodes 1071 through 107L. Likewise, any of worker nodes 1071 through 107L can write a response into the request/response shared memory 106 that can later be retrieved by the connection manager 102. Thus the request/response shared memory 106 provides for the efficient transfer of request/response data between the connection manager 102 and the multiple proprietary worker nodes 1071 through 107L.
If the request is to be forwarded to the standards based software suite 104, notification of the request is sent to the dispatcher 108 that is associated with the standards based software suite 104. As observed in FIG. 1A, the standards-based software suite 104 is a Java based software suite (in particular, a Java 2 Enterprise Edition (J2EE) suite) that includes multiple worker nodes 1091 through 109N.
A Java Virtual Machine is associated with each worker node for executing the worker node's abstract application software code. For each request, dispatcher 108 decides which one of the N worker nodes is best able to handle the request (e.g., through a load balancing algorithm). Because no shared memory structure exists within the standards based software suite 104 for transferring client session information between the connection manager 102 and the worker nodes 1091 through 109N, separate internal connections have to be established to send both notification of the request and the request itself to the dispatcher 108 from connection manager 102 for each worker node. The dispatcher 108 then forwards each request to its proper worker node.
A virtual machine (VM), as is well understood in the art, is an abstract machine that converts (or “interprets”) abstract code into code that is understandable to a particular type of a hardware platform (e.g., a particular type of processor). Because virtual machines operate at the instruction level they tend to have processor-like characteristics, and, therefore, can be viewed as having their own associated memory. The memory used by a functioning virtual machine is typically modeled as being local (or “private”) to the virtual machine.
Various problems exist with respect to the prior art application server 100 of FIG. 1A. For example, as application development projects grow larger, class loading becomes both increasingly important and cumbersome. “Class loading” is a technique used primarily by software developers to make programming code truly mobile. For example, every mobile code system requires the ability to dynamically load code from outside a system (e.g., from a network or a disk) into the system. In Java, this loading of the code is performed by class loaders. In other words, class loading provides an essential benefit of having a Java virtual machine by converting a named class into the bits responsible for implementing that class. Also, because of the class loading technique, the Java runtime does not need to know anything about files and file system when running Java programs. However, the conventional class loading does not provide any kind of versioning mechanism, which often results in compatibility problems.
FIG. 1B illustrates a prior art class loading mechanism hierarchy 150. In the illustrated embodiment, various types of class loaders 152-156 are arranged in tree-based hierarchy 150 having the bootstrap class loaders 152 as the root of the tree. The bootstrap class loader 152 is the only class loader without a parent, while each of the user-defined class loaders is assigned a parent class loader. Generally, the default parent class loader is the system (or application) class loader 156. In a typical Java virtual machine, a bootstrap class loader 152 and two user-defined class loaders, an extension class loader 154 and a system class loader 156, are provided. The bootstrap class loader 152 is responsible for loading the core Java classes (e.g., java.* and javax.*) into the virtual machine. The extension class loader 154 loads classes from the Java Runtime Environment's extension directories, while the system class loader 156 is regarded as responsible for loading classes from the system class path. The delegation model, as referenced by dotted arrows, runs from the system class loader 156 to the extension class loader 154 to the bootstrap class loader 152.
Although the conventional class loading mechanism hierarchy 150 provides the developer with an extensive flexibility when assembling and extending an application, it is also severely limited with dealing with independent parts of coding having different coding versions. When relatively independent parts of coding have to work together, changing design or communicating protocol or interfaces becomes problematic or even impossible for newer versions, particularly when the new version has to work with the old version of coding. For example, classes are not capable of receiving constant enhancements during development of different versions, since the same class is required to be in compliance with different versions. This problem is exasperated when a complex application with relatively independent parts needs to use different versions of the same base application programming interface (API). In this case, a part of the application remains unchanged relying on old API classes, while another part of the application is further in development using newer API classes. The problem is further complicated when different interfaces and/or services are used across the development project.